package com.jaeger.ninegridimageview;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.Resource;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;
import ohos.multimodalinput.event.TouchEvent;

import java.util.Optional;

/**
 * 自定义布局中的子view继承Image
 */
public class GridImageView extends Image implements Component.TouchEventListener, Component.BindStateChangedListener {
    private static final String TAG = "GridImageView";

    public GridImageView(Context context, AttrSet attrs) {
        super(context, attrs);
        final Paint mPaint = new Paint();
        mPaint.setDither(true);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        setTouchEventListener(this);
    }

    public GridImageView(Context context) {
        this(context,null);
    }

    /**
     * 根据图片资源id获取位图
     *
     * @param context 上下文
     * @param id      图片的资源id
     * @return PixelMap 位图
     */
    private static PixelMap decodeResource(Context context, int id) {
        try {
            String path = context.getResourceManager().getMediaPath(id);
            if (path.isEmpty()) {
                return null;
            }
            RawFileEntry assetManager = context.getResourceManager().getRawFileEntry(path);
            ImageSource.SourceOptions options = new ImageSource.SourceOptions();
            options.formatHint = "image/png";
            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            Resource asset = assetManager.openRawFile();
            ImageSource source = ImageSource.create(asset, options);
            return Optional.ofNullable(source.createPixelmap(decodingOptions)).get();
        } catch (Exception e) {
            LogUtil.error(TAG,e.getMessage());
        }
        return null;
    }


    private PixelMap mSrcPixelMap;
    private PixelMap mGrayPixelMap;

    private boolean isTouchFlag = false;

    @Override
    public void setPixelMap(int resId) {
        if(!isTouchFlag) {
            this.mSrcPixelMap = decodeResource(getContext(), resId);
            createGray();
        }
        isTouchFlag = false;
        super.setPixelMap(resId);
    }
    private static Paint DEFAULT_PAINT = new Paint();
    private void createGray(){
        DEFAULT_PAINT.setDither(true);
        DEFAULT_PAINT.setFilterBitmap(true);
        // 首先生成蒙版底 mMaskBitmap
        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(mSrcPixelMap.getImageInfo().size.width, mSrcPixelMap.getImageInfo().size.height);
        initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
        mGrayPixelMap = PixelMap.create(initializationOptions);
        Canvas canvas = new Canvas(new Texture(mGrayPixelMap));
        // 绘制蒙版为透明灰色
        int maskColor = new Color(0x50000000).getValue();
        canvas.drawPixelMapHolder(new PixelMapHolder(mSrcPixelMap), 0, 0, DEFAULT_PAINT);
        canvas.drawColor(maskColor, Canvas.PorterDuffMode.SRC_OVER);
        clear(canvas);
    }

    private static void clear(Canvas canvas) {
        canvas.setTexture(null);
    }

    @Override
    public void setPixelMap(PixelMap pixelMap) {
        if(!isTouchFlag) {
            this.mSrcPixelMap = pixelMap;
            createGray();
        }
        isTouchFlag = false;
        super.setPixelMap(pixelMap);
    }


    @Override
    public boolean onTouchEvent(Component component, TouchEvent event) {
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                if(mGrayPixelMap!= null) {
                    isTouchFlag = true;
                    setPixelMap(mGrayPixelMap);
                }
                break;
            case TouchEvent.POINT_MOVE:
                break;
            case TouchEvent.CANCEL:
            case TouchEvent.PRIMARY_POINT_UP:
                if(mSrcPixelMap != null) {
                    isTouchFlag = true;
                    setPixelMap(mSrcPixelMap);
                }
                break;
        }
        return true;
    }

    @Override
    public void onComponentBoundToWindow(Component component) {
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {
        setImageElement(null);
    }
}